package org.ielts.repository.security;

import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.ielts.domain.security.Role;
import org.ielts.domain.security.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.stereotype.Repository;
import com.yifeng.dao.HibernateRepository;
import com.yifeng.page.table.Paginations;

@Repository
public class UserRepository extends HibernateRepository<User, String> {

	public User findUserByNameAndPassword(String name, String pwd) {
		DetachedCriteria detachedCriteria = DetachedCriteria.forClass(User.class);

		detachedCriteria.add(Restrictions.eq("name", name)).add(Restrictions.eq("password", pwd));

		@SuppressWarnings("unchecked")
		List<User> users = hibernateTemplate.findByCriteria(detachedCriteria);

		return uniqueResult(users);
	}

	public Page<User> findAll(String name, Pageable pageable) {
		DetachedCriteria detachedCriteria = DetachedCriteria.forClass(User.class);

		detachedCriteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

		if (StringUtils.isNotBlank(name)) {
			detachedCriteria.add(Restrictions.like("name", name, MatchMode.START));
		}
		detachedCriteria.addOrder(Order.desc("createTime"));

		@SuppressWarnings("unchecked")
		List<User> users = hibernateTemplate.findByCriteria(detachedCriteria, pageable.getOffset(),
				pageable.getPageSize());

		long total = firstLongQuery(detachedCriteria);

		return new PageImpl<User>(users, pageable, total);
	}

	public Iterable<User> findByRoleName(String role) {
		DetachedCriteria detachedCriteria = createDetachedCriteria();

		detachedCriteria.createAlias("roles", "r").add(Restrictions.eq("r.name", role)).addOrder(Order.asc("name"));

		@SuppressWarnings("unchecked")
		List<User> list = hibernateTemplate.findByCriteria(detachedCriteria);

		return list;
	}

	public User findByLoginName(String loginName) {
		DetachedCriteria detachedCriteria = createDetachedCriteria();

		detachedCriteria.add(Restrictions.eq("loginName", loginName));

		User user = uniqueResult(detachedCriteria);

		return user;
	}

	public User findUserByLoginNameAndPassword(String loginName, String pwd) {

		DetachedCriteria detachedCriteria = createDetachedCriteria();

		detachedCriteria.add(Restrictions.eq("loginName", loginName)).add(Restrictions.eq("password", pwd));

		User user = uniqueResult(detachedCriteria);

		return user;
	}

	public List<User> findByRoleNameLike(String name_like) {

		String hql = "select distinct u from User u left join u.roles r where r.name like ? ";

		@SuppressWarnings("unchecked")
		List<User> users = hibernateTemplate.find(hql, name_like);
		return users;
	}

	public User findByNameAndRole(String name, String role) {
		DetachedCriteria detachedCriteria = createDetachedCriteria();
		detachedCriteria.add(Restrictions.eq("name", name)).createCriteria("roles").add(Restrictions.eq("name", role));

		User user = uniqueResult(detachedCriteria);

		return user;
	}

	public User findByNo(String no) {
		DetachedCriteria detachedCriteria = createDetachedCriteria();
		detachedCriteria.add(Restrictions.eq("no", no));

		User user = uniqueResult(detachedCriteria);

		return user;
	}
}
